/*
 *------------------------------------------------------------------------------
 * @File      :    sc4238_mipi.c
 * @Date      :    2021-7-7
 * @Author    :    lomboswer <lomboswer@lombotech.com>
 * @Brief     :    Source file for MDP(Media Development Platform).
 *
 * Copyright (C) 2020-2021, LomboTech Co.Ltd. All rights reserved.
 *------------------------------------------------------------------------------
 */
#include "ei_comm_camera.h"
#include "camera_usr.h"

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */

#define SNS_ID 4238
#define SNS_NAME  "sc4238_mipi"
#define DEV_TYPE MCSI
static VISS_DEV gaVissDev[ISP_MAX_DEV_NUM] = {-1};
static SNS_STATE_S g_sastSns[VISS_MAX_DEV_NUM];

#define MAX_2688X1520_SHORT_EXP           (0xba)
#define MAX_2592X1520_SHORT_EXP           (0xb6)
#if 0
/* 0x2b_FT_SC4238_MIPI_27MInput_720Mbps_4lane_10bit_1080_30fps_VC_HDR_non_con */
static const SNS_REG_S s_aRaw1080p4lane30fps10bit2fHDR[] = {
	{0x0103,0x01},
	{0x0100,0x00},
	{0x36e9,0x80},
	{0x36f9,0x80},
	{0x3018,0x72},
	{0x301f,0xb9},
	{0x3031,0x0a},
	{0x3037,0x20},
	{0x3038,0x22},
	{0x3106,0x81},
	{0x3200,0x01},
	{0x3201,0x80},
	{0x3202,0x00},
	{0x3203,0xdc},
	{0x3204,0x09},
	{0x3205,0x07},
	{0x3206,0x05},
	{0x3207,0x1b},
	{0x3208,0x07},
	{0x3209,0x80},
	{0x320a,0x04},
	{0x320b,0x38},
	{0x320c,0x06},
	{0x320d,0x0e},
	{0x320e,0x0c},
	{0x320f,0x18},
	{0x3210,0x00},
	{0x3211,0x04},
	{0x3212,0x00},
	{0x3213,0x04},
	{0x3220,0x53},
	{0x3225,0x02},
	{0x3235,0x18},
	{0x3236,0x2f},
	{0x3237,0x02},
	{0x3238,0xc7},
	{0x3250,0x3f},
	{0x3251,0x88},
	{0x3253,0x0a},
	{0x325f,0x0c},
	{0x3273,0x01},
	{0x3301,0x12},
	{0x3304,0x38},
	{0x3305,0x00},
	{0x3306,0x68},
	{0x3307,0x06},
	{0x3308,0x10},
	{0x3309,0x68},
	{0x330a,0x00},
	{0x330b,0xe8},
	{0x330d,0x20},
	{0x330e,0x1a},
	{0x3314,0x94},
	{0x3317,0x04},
	{0x3318,0x02},
	{0x331e,0x29},
	{0x331f,0x59},
	{0x3320,0x09},
	{0x3332,0x20},
	{0x334c,0x10},
	{0x3350,0x20},
	{0x3352,0x02},
	{0x3356,0x1f},
	{0x3358,0x20},
	{0x335c,0x20},
	{0x335e,0x02},
	{0x335f,0x04},
	{0x3363,0x00},
	{0x3364,0x1e},
	{0x3366,0x92},
	{0x336d,0x03},
	{0x337a,0x08},
	{0x337b,0x10},
	{0x337c,0x06},
	{0x337d,0x0a},
	{0x337f,0x2d},
	{0x3390,0x04},
	{0x3391,0x08},
	{0x3392,0x38},
	{0x3393,0x20},
	{0x3394,0x30},
	{0x3395,0x30},
	{0x3399,0xff},
	{0x339e,0x20},
	{0x33a0,0x20},
	{0x33a2,0x08},
	{0x33a3,0x0c},
	{0x33a4,0x20},
	{0x33a8,0x20},
	{0x33aa,0x20},
	{0x33e0,0xa0},
	{0x33e1,0x08},
	{0x33e2,0x00},
	{0x33e3,0x10},
	{0x33e4,0x10},
	{0x33e5,0x00},
	{0x33e6,0x10},
	{0x33e7,0x10},
	{0x33e8,0x00},
	{0x33e9,0x10},
	{0x33ea,0x16},
	{0x33eb,0x00},
	{0x33ec,0x10},
	{0x33ed,0x18},
	{0x33ee,0xa0},
	{0x33ef,0x08},
	{0x33f4,0x00},
	{0x33f5,0x10},
	{0x33f6,0x10},
	{0x33f7,0x00},
	{0x33f8,0x10},
	{0x33f9,0x10},
	{0x33fa,0x00},
	{0x33fb,0x10},
	{0x33fc,0x16},
	{0x33fd,0x00},
	{0x33fe,0x10},
	{0x33ff,0x18},
	{0x360f,0x05},
	{0x3622,0xee},
	{0x3625,0x0a},
	{0x3630,0xa8},
	{0x3631,0x80},
	{0x3633,0x44},
	{0x3634,0x54},
	{0x3635,0x60},
	{0x3636,0x20},
	{0x3637,0x22},
	{0x3638,0x2a},
	{0x363a,0x1f},
	{0x363b,0x03},
	{0x3641,0x00},
	{0x366e,0x04},
	{0x3670,0x4a},
	{0x3671,0xee},
	{0x3672,0x6e},
	{0x3673,0x6e},
	{0x3674,0x70},
	{0x3675,0x40},
	{0x3676,0x45},
	{0x367a,0x08},
	{0x367b,0x38},
	{0x367c,0x08},
	{0x367d,0x38},
	{0x3690,0x43},
	{0x3691,0x64},
	{0x3692,0x65},
	{0x3699,0x9f},
	{0x369a,0x9f},
	{0x369b,0x9f},
	{0x369c,0x08},
	{0x369d,0x18},
	{0x36a2,0x08},
	{0x36a3,0x08},
	{0x36ea,0x36},
	{0x36eb,0x04},
	{0x36ec,0x0c},
	{0x36ed,0x14},
	{0x36fa,0x36},
	{0x36fb,0x04},
	{0x36fc,0x00},
	{0x36fd,0x14},
	{0x3902,0xc5},
	{0x3905,0xd8},
	{0x3908,0x11},
	{0x391b,0x80},
	{0x391c,0x0f},
	{0x391d,0x21},
	{0x3933,0x28},
	{0x3934,0x20},
	{0x3940,0x68},
	{0x3942,0x08},
	{0x3943,0x28},
	{0x3980,0x00},
	{0x3981,0x00},
	{0x3982,0x00},
	{0x3983,0x00},
	{0x3984,0x00},
	{0x3985,0x00},
	{0x3986,0x00},
	{0x3987,0x00},
	{0x3988,0x00},
	{0x3989,0x00},
	{0x398a,0x00},
	{0x398b,0x08},
	{0x398c,0x00},
	{0x398d,0x10},
	{0x398e,0x00},
	{0x398f,0x18},
	{0x3990,0x00},
	{0x3991,0x20},
	{0x3992,0x03},
	{0x3993,0xd8},
	{0x3994,0x03},
	{0x3995,0xe0},
	{0x3996,0x03},
	{0x3997,0xf0},
	{0x3998,0x03},
	{0x3999,0xf8},
	{0x399a,0x00},
	{0x399b,0x00},
	{0x399c,0x00},
	{0x399d,0x08},
	{0x399e,0x00},
	{0x399f,0x10},
	{0x39a0,0x00},
	{0x39a1,0x18},
	{0x39a2,0x00},
	{0x39a3,0x28},
	{0x39af,0x58},
	{0x39b5,0x30},
	{0x39b6,0x00},
	{0x39b7,0x34},
	{0x39b8,0x00},
	{0x39b9,0x00},
	{0x39ba,0x34},
	{0x39bb,0x00},
	{0x39bc,0x00},
	{0x39bd,0x00},
	{0x39be,0x00},
	{0x39bf,0x00},
	{0x39c0,0x00},
	{0x39c1,0x00},
	{0x39c5,0x21},
	{0x39c8,0x00},
	{0x39db,0x20},
	{0x39dc,0x00},
	{0x39de,0x20},
	{0x39df,0x00},
	{0x39e0,0x00},
	{0x39e1,0x00},
	{0x39e2,0x00},
	{0x39e3,0x00},
	{0x39e8,0x03},
	{0x3e00,0x01},
	{0x3e01,0x6a},
	{0x3e02,0x00},
	{0x3e03,0x0b},
	{0x3e04,0x16},
	{0x3e05,0xa0},
	{0x3e06,0x00},
	{0x3e07,0x80},
	{0x3e08,0x03},
	{0x3e09,0x40},
	{0x3e10,0x00},
	{0x3e11,0x80},
	{0x3e12,0x03},
	{0x3e13,0x40},
	{0x3e14,0xb1},
	{0x3e23,0x00},
	{0x3e24,0xba},
	{0x3e25,0x03},
	{0x3e26,0x40},
	{0x4500,0x08},
	{0x4501,0xa4},
	{0x4506,0x3e},
	{0x4509,0x10},
	{0x4800,0x64},
	{0x4816,0x51},
	{0x4818,0x00},
	{0x4819,0x30},
	{0x481a,0x00},
	{0x481b,0x28},
	{0x481c,0x00},
	{0x481d,0xe8},
	{0x4821,0x02},
	{0x4822,0x00},
	{0x4823,0x28},
	{0x4828,0x00},
	{0x4829,0x10},
	{0x4837,0x1b},
	{0x5784,0x10},
	{0x5785,0x08},
	{0x5787,0x00},
	{0x5788,0x00},
	{0x5789,0x00},
	{0x578a,0x06},
	{0x578b,0x06},
	{0x578c,0x00},
	{0x5790,0x10},
	{0x5791,0x10},
	{0x5792,0x00},
	{0x5793,0x10},
	{0x5794,0x10},
	{0x5795,0x00},
	{0x57c4,0x10},
	{0x57c5,0x08},
	{0x57c7,0x00},
	{0x57c8,0x00},
	{0x57c9,0x00},
	{0x57ca,0x06},
	{0x57cb,0x06},
	{0x57cc,0x00},
	{0x57d0,0x10},
	{0x57d1,0x10},
	{0x57d2,0x00},
	{0x57d3,0x10},
	{0x57d4,0x10},
	{0x57d5,0x00},
	{0x5988,0x86},
	{0x598e,0x0b},
	{0x598f,0xc6},
	{0x5a88,0x86},
	{0x5a8e,0x0b},
	{0x5a8f,0xc6},
	{0x36e9,0x44},
	{0x36f9,0x44},
    //{0x0100,0x01},
};

static const SNS_REG_S s_aRaw1080p4lane30fps10bit[] = {
	{0x0103,0x01},
	{0x0100,0x00},
	{0x36e9,0x80},
	{0x36f9,0x80},
	{0x3018,0x72},
	{0x301f,0xb8},
	{0x3031,0x0a},
	{0x3037,0x20},
	{0x3038,0x22},
	{0x3106,0x81},
	{0x3200,0x01},
	{0x3201,0x80},
	{0x3202,0x00},
	{0x3203,0xdc},
	{0x3204,0x09},
	{0x3205,0x07},
	{0x3206,0x05},
	{0x3207,0x1b},
	{0x3208,0x07},
	{0x3209,0x80},
	{0x320a,0x04},
	{0x320b,0x38},
	{0x320c,0x05},
	{0x320d,0xa0},
	{0x320e,0x06},
	{0x320f,0x1a},
	{0x3210,0x00},
	{0x3211,0x04},
	{0x3212,0x00},
	{0x3213,0x04},
	{0x3251,0x88},
	{0x3253,0x0a},
	{0x325f,0x0c},
	{0x3273,0x01},
	{0x3301,0x30},
	{0x3304,0x30},
	{0x3306,0x70},
	{0x3308,0x10},
	{0x3309,0x50},
	{0x330b,0xf0},
	{0x330e,0x14},
	{0x3314,0x94},
	{0x331e,0x29},
	{0x331f,0x49},
	{0x3320,0x09},
	{0x334c,0x10},
	{0x3352,0x02},
	{0x3356,0x1f},
	{0x335e,0x02},
	{0x335f,0x04},
	{0x3363,0x00},
	{0x3364,0x1e},
	{0x3366,0x92},
	{0x336d,0x03},
	{0x337a,0x08},
	{0x337b,0x10},
	{0x337c,0x06},
	{0x337d,0x0a},
	{0x337f,0x2d},
	{0x3390,0x08},
	{0x3391,0x18},
	{0x3392,0x38},
	{0x3393,0x30},
	{0x3394,0x30},
	{0x3395,0x30},
	{0x3399,0xff},
	{0x33a2,0x08},
	{0x33a3,0x0c},
	{0x33e0,0xa0},
	{0x33e1,0x08},
	{0x33e2,0x00},
	{0x33e3,0x10},
	{0x33e4,0x10},
	{0x33e5,0x00},
	{0x33e6,0x10},
	{0x33e7,0x10},
	{0x33e8,0x00},
	{0x33e9,0x10},
	{0x33ea,0x16},
	{0x33eb,0x00},
	{0x33ec,0x10},
	{0x33ed,0x18},
	{0x33ee,0xa0},
	{0x33ef,0x08},
	{0x33f4,0x00},
	{0x33f5,0x10},
	{0x33f6,0x10},
	{0x33f7,0x00},
	{0x33f8,0x10},
	{0x33f9,0x10},
	{0x33fa,0x00},
	{0x33fb,0x10},
	{0x33fc,0x16},
	{0x33fd,0x00},
	{0x33fe,0x10},
	{0x33ff,0x18},
	{0x360f,0x05},
	{0x3622,0xee},
	{0x3625,0x0a},
	{0x3630,0xa8},
	{0x3631,0x80},
	{0x3633,0x44},
	{0x3634,0x34},
	{0x3635,0x60},
	{0x3636,0x20},
	{0x3637,0x11},
	{0x3638,0x2a},
	{0x363a,0x1f},
	{0x363b,0x03},
	{0x366e,0x04},
	{0x3670,0x4a},
	{0x3671,0xee},
	{0x3672,0x0e},
	{0x3673,0x0e},
	{0x3674,0x70},
	{0x3675,0x40},
	{0x3676,0x45},
	{0x367a,0x08},
	{0x367b,0x38},
	{0x367c,0x08},
	{0x367d,0x38},
	{0x3690,0x43},
	{0x3691,0x63},
	{0x3692,0x63},
	{0x3699,0x80},
	{0x369a,0x9f},
	{0x369b,0x9f},
	{0x369c,0x08},
	{0x369d,0x38},
	{0x36a2,0x08},
	{0x36a3,0x38},
	{0x36ea,0x36},
	{0x36eb,0x14},
	{0x36ec,0x0c},
	{0x36ed,0x24},
	{0x36fa,0x36},
	{0x36fb,0x09},
	{0x36fc,0x00},
	{0x36fd,0x24},
	{0x3902,0xc5},
	{0x3905,0xd8},
	{0x3908,0x11},
	{0x391b,0x80},
	{0x391c,0x0f},
	{0x391d,0x24},
	{0x3933,0x28},
	{0x3934,0x20},
	{0x3940,0x6c},
	{0x3942,0x08},
	{0x3943,0x28},
	{0x3980,0x00},
	{0x3981,0x00},
	{0x3982,0x00},
	{0x3983,0x00},
	{0x3984,0x00},
	{0x3985,0x00},
	{0x3986,0x00},
	{0x3987,0x00},
	{0x3988,0x00},
	{0x3989,0x00},
	{0x398a,0x00},
	{0x398b,0x04},
	{0x398c,0x00},
	{0x398d,0x04},
	{0x398e,0x00},
	{0x398f,0x08},
	{0x3990,0x00},
	{0x3991,0x10},
	{0x3992,0x03},
	{0x3993,0xd8},
	{0x3994,0x03},
	{0x3995,0xe0},
	{0x3996,0x03},
	{0x3997,0xf0},
	{0x3998,0x03},
	{0x3999,0xf8},
	{0x399a,0x00},
	{0x399b,0x00},
	{0x399c,0x00},
	{0x399d,0x08},
	{0x399e,0x00},
	{0x399f,0x10},
	{0x39a0,0x00},
	{0x39a1,0x18},
	{0x39a2,0x00},
	{0x39a3,0x28},
	{0x39af,0x58},
	{0x39b5,0x30},
	{0x39b6,0x00},
	{0x39b7,0x34},
	{0x39b8,0x00},
	{0x39b9,0x00},
	{0x39ba,0x34},
	{0x39bb,0x00},
	{0x39bc,0x00},
	{0x39bd,0x00},
	{0x39be,0x00},
	{0x39bf,0x00},
	{0x39c0,0x00},
	{0x39c1,0x00},
	{0x39c5,0x21},
	{0x39c8,0x00},
	{0x39db,0x20},
	{0x39dc,0x00},
	{0x39de,0x20},
	{0x39df,0x00},
	{0x39e0,0x00},
	{0x39e1,0x00},
	{0x39e2,0x00},
	{0x39e3,0x00},
	{0x3e00,0x00},
	{0x3e01,0xc2},
	{0x3e02,0xa0},
	{0x3e03,0x0b},
	{0x3e06,0x00},
	{0x3e07,0x80},
	{0x3e08,0x03},
	{0x3e09,0x40},
	{0x3e14,0xb1},
	{0x3e25,0x03},
	{0x3e26,0x40},
	{0x4501,0xb4},
	{0x4509,0x20},
	{0x4800,0x64},
	{0x4818,0x00},
	{0x4819,0x30},
	{0x481a,0x00},
	{0x481b,0x0b},
	{0x481c,0x00},
	{0x481d,0xc8},
	{0x4821,0x02},
	{0x4822,0x00},
	{0x4823,0x03},
	{0x4828,0x00},
	{0x4829,0x02},
	{0x4837,0x3b},
	{0x5784,0x10},
	{0x5785,0x08},
	{0x5787,0x06},
	{0x5788,0x06},
	{0x5789,0x00},
	{0x578a,0x06},
	{0x578b,0x06},
	{0x578c,0x00},
	{0x5790,0x10},
	{0x5791,0x10},
	{0x5792,0x00},
	{0x5793,0x10},
	{0x5794,0x10},
	{0x5795,0x00},
	{0x57c4,0x10},
	{0x57c5,0x08},
	{0x57c7,0x06},
	{0x57c8,0x06},
	{0x57c9,0x00},
	{0x57ca,0x06},
	{0x57cb,0x06},
	{0x57cc,0x00},
	{0x57d0,0x10},
	{0x57d1,0x10},
	{0x57d2,0x00},
	{0x57d3,0x10},
	{0x57d4,0x10},
	{0x57d5,0x00},
	{0x5988,0x86},
	{0x598e,0x05},
	{0x598f,0x6c},
	{0x36e9,0x54},
	{0x36f9,0x54},
    //{0x0100,0x01},
};

#endif
/* 0x2b_FT_SC4238_MIPI_27MInput_720Mbps_4lane_10bit_2688x1520_30fps_VC_HDR_non_con */
static const SNS_REG_S s_aRaw2688X1520p4lane30fps10bit2fHDR[] = {
    {0x0103,0x01},
    {0x0100,0x00},
    {0x36e9,0x80},
    {0x36f9,0x80},
    {0x3018,0x72},
    {0x301f,0x85},
    {0x3031,0x0a},
    {0x3037,0x20},
    {0x3038,0x22},
    {0x3106,0x81},
    {0x3200,0x00},
    {0x3201,0x00},
    {0x3202,0x00},
    {0x3203,0x00},
    {0x3204,0x0a},
    {0x3205,0x87},
    {0x3206,0x05},
    {0x3207,0xf7},
    {0x3208,0x0a},
    {0x3209,0x80},
    {0x320a,0x05},
    {0x320b,0xf0},
    {0x320c,0x06},
    {0x320d,0x0e},
    {0x320e,0x0c},
    {0x320f,0x18},
    {0x3211,0x04},
    {0x3213,0x04},
    {0x3220,0x53},
    {0x3225,0x02},
    {0x3235,0x18},
    {0x3236,0x2f},
    {0x3237,0x02},
    {0x3238,0xc7},
    {0x3250,0x3f},
    {0x3251,0x88},
    {0x3253,0x0a},
    {0x325f,0x0c},
    {0x3273,0x01},
    {0x3301,0x12},
    {0x3304,0x38},
    {0x3305,0x00},
    {0x3306,0x68},
    {0x3307,0x06},
    {0x3308,0x10},
    {0x3309,0x68},
    {0x330a,0x00},
    {0x330b,0xe8},
    {0x330d,0x20},
    {0x330e,0x1a},
    {0x3314,0x94},
    {0x3317,0x04},
    {0x3318,0x02},
    {0x331e,0x29},
    {0x331f,0x59},
    {0x3320,0x09},
    {0x3332,0x20},
    {0x334c,0x10},
    {0x3350,0x20},
    {0x3352,0x02},
    {0x3356,0x1f},
    {0x3358,0x20},
    {0x335c,0x20},
    {0x335e,0x02},
    {0x335f,0x04},
    {0x3363,0x00},
    {0x3364,0x1e},
    {0x3366,0x92},
    {0x336d,0x03},
    {0x337a,0x08},
    {0x337b,0x10},
    {0x337c,0x06},
    {0x337d,0x0a},
    {0x337f,0x2d},
    {0x3390,0x04},
    {0x3391,0x08},
    {0x3392,0x38},
    {0x3393,0x20},
    {0x3394,0x30},
    {0x3395,0x30},
    {0x3399,0xff},
    {0x339e,0x20},
    {0x33a0,0x20},
    {0x33a2,0x08},
    {0x33a3,0x0c},
    {0x33a4,0x20},
    {0x33a8,0x20},
    {0x33aa,0x20},
    {0x33e0,0xa0},
    {0x33e1,0x08},
    {0x33e2,0x00},
    {0x33e3,0x10},
    {0x33e4,0x10},
    {0x33e5,0x00},
    {0x33e6,0x10},
    {0x33e7,0x10},
    {0x33e8,0x00},
    {0x33e9,0x10},
    {0x33ea,0x16},
    {0x33eb,0x00},
    {0x33ec,0x10},
    {0x33ed,0x18},
    {0x33ee,0xa0},
    {0x33ef,0x08},
    {0x33f4,0x00},
    {0x33f5,0x10},
    {0x33f6,0x10},
    {0x33f7,0x00},
    {0x33f8,0x10},
    {0x33f9,0x10},
    {0x33fa,0x00},
    {0x33fb,0x10},
    {0x33fc,0x16},
    {0x33fd,0x00},
    {0x33fe,0x10},
    {0x33ff,0x18},
    {0x360f,0x05},
    {0x3622,0xee},
    {0x3625,0x0a},
    {0x3630,0xa8},
    {0x3631,0x80},
    {0x3633,0x44},
    {0x3634,0x54},
    {0x3635,0x60},
    {0x3636,0x20},
    {0x3637,0x22},
    {0x3638,0x2a},
    {0x363a,0x1f},
    {0x363b,0x03},
    {0x3641,0x00},
    {0x366e,0x04},
    {0x3670,0x4a},
    {0x3671,0xee},
    {0x3672,0x6e},
    {0x3673,0x6e},
    {0x3674,0x70},
    {0x3675,0x40},
    {0x3676,0x45},
    {0x367a,0x08},
    {0x367b,0x38},
    {0x367c,0x08},
    {0x367d,0x38},
    {0x3690,0x43},
    {0x3691,0x64},
    {0x3692,0x65},
    {0x3699,0x9f},
    {0x369a,0x9f},
    {0x369b,0x9f},
    {0x369c,0x08},
    {0x369d,0x18},
    {0x36a2,0x08},
    {0x36a3,0x08},
    {0x36ea,0x36},
    {0x36eb,0x04},
    {0x36ec,0x0c},
    {0x36ed,0x14},
    {0x36fa,0x36},
    {0x36fb,0x04},
    {0x36fc,0x00},
    {0x36fd,0x14},
    {0x3902,0xc5},
    {0x3905,0xd8},
    {0x3908,0x11},
    {0x391b,0x80},
    {0x391c,0x0f},
    {0x391d,0x21},
    {0x3933,0x28},
    {0x3934,0x20},
    {0x3940,0x68},
    {0x3942,0x08},
    {0x3943,0x28},
    {0x3980,0x00},
    {0x3981,0x00},
    {0x3982,0x00},
    {0x3983,0x00},
    {0x3984,0x00},
    {0x3985,0x00},
    {0x3986,0x00},
    {0x3987,0x00},
    {0x3988,0x00},
    {0x3989,0x00},
    {0x398a,0x00},
    {0x398b,0x08},
    {0x398c,0x00},
    {0x398d,0x10},
    {0x398e,0x00},
    {0x398f,0x18},
    {0x3990,0x00},
    {0x3991,0x20},
    {0x3992,0x03},
    {0x3993,0xd8},
    {0x3994,0x03},
    {0x3995,0xe0},
    {0x3996,0x03},
    {0x3997,0xf0},
    {0x3998,0x03},
    {0x3999,0xf8},
    {0x399a,0x00},
    {0x399b,0x00},
    {0x399c,0x00},
    {0x399d,0x08},
    {0x399e,0x00},
    {0x399f,0x10},
    {0x39a0,0x00},
    {0x39a1,0x18},
    {0x39a2,0x00},
    {0x39a3,0x28},
    {0x39af,0x58},
    {0x39b5,0x30},
    {0x39b6,0x00},
    {0x39b7,0x34},
    {0x39b8,0x00},
    {0x39b9,0x00},
    {0x39ba,0x34},
    {0x39bb,0x00},
    {0x39bc,0x00},
    {0x39bd,0x00},
    {0x39be,0x00},
    {0x39bf,0x00},
    {0x39c0,0x00},
    {0x39c1,0x00},
    {0x39c5,0x21},
    {0x39c8,0x00},
    {0x39db,0x20},
    {0x39dc,0x00},
    {0x39de,0x20},
    {0x39df,0x00},
    {0x39e0,0x00},
    {0x39e1,0x00},
    {0x39e2,0x00},
    {0x39e3,0x00},
    {0x39e8,0x03},
    {0x3e00,0x01},
    {0x3e01,0x6a},
    {0x3e02,0x00},
    {0x3e03,0x0b},
    {0x3e04,0x16},
    {0x3e05,0xa0},
    {0x3e06,0x00},
    {0x3e07,0x80},
    {0x3e08,0x03},
    {0x3e09,0x40},
    {0x3e10,0x00},
    {0x3e11,0x80},
    {0x3e12,0x03},
    {0x3e13,0x40},
    {0x3e14,0xb1},
    {0x3e23,0x00},
    {0x3e24,0xba},
    {0x3e25,0x03},
    {0x3e26,0x40},
    {0x4500,0x08},
    {0x4501,0xa4},
    {0x4506,0x3e},
    {0x4509,0x10},
    {0x4800,0x64},
    {0x4816,0x51},
    {0x4818,0x00},
    {0x4819,0x30},
    {0x481a,0x00},
    {0x481b,0x28},
    {0x481c,0x00},
    {0x481d,0xe8},
    {0x4821,0x02},
    {0x4822,0x00},
    {0x4823,0x28},
    {0x4828,0x00},
    {0x4829,0x10},
    {0x4837,0x1b},
    {0x5784,0x10},
    {0x5785,0x08},
    {0x5787,0x00},
    {0x5788,0x00},
    {0x5789,0x00},
    {0x578a,0x06},
    {0x578b,0x06},
    {0x578c,0x00},
    {0x5790,0x10},
    {0x5791,0x10},
    {0x5792,0x00},
    {0x5793,0x10},
    {0x5794,0x10},
    {0x5795,0x00},
    {0x57c4,0x10},
    {0x57c5,0x08},
    {0x57c7,0x00},
    {0x57c8,0x00},
    {0x57c9,0x00},
    {0x57ca,0x06},
    {0x57cb,0x06},
    {0x57cc,0x00},
    {0x57d0,0x10},
    {0x57d1,0x10},
    {0x57d2,0x00},
    {0x57d3,0x10},
    {0x57d4,0x10},
    {0x57d5,0x00},
    {0x5988,0x86},
    {0x598e,0x0b},
    {0x598f,0xc6},
    {0x5a88,0x86},
    {0x5a8e,0x0b},
    {0x5a8f,0xc6},
    {0x36e9,0x44},
    {0x36f9,0x44},
    //{0x0100,0x01},
};

static const SNS_REG_S s_aRaw2688X1520p4lane30fps12bit[] = {
    {0x0103,0x01},
    {0x0100,0x00},
    {0x36e9,0x80},
    {0x36f9,0x80},
    {0x3018,0x72},
    {0x301f,0x86},
    {0x3031,0x0c},
    {0x3037,0x40},
    {0x3038,0x22},
    {0x3106,0x81},
    {0x3200,0x00},
    {0x3201,0x00},
    {0x3202,0x00},
    {0x3203,0x00},
    {0x3204,0x0a},
    {0x3205,0x87},
    {0x3206,0x05},
    {0x3207,0xf7},
    {0x3208,0x0a},
    {0x3209,0x80},
    {0x320a,0x05},
    {0x320b,0xf0},
    {0x320c,0x05},
    {0x320d,0xa0},
    {0x320e,0x06},
    {0x320f,0x1a},
    {0x3211,0x04},
    {0x3213,0x04},
    {0x3251,0x88},
    {0x3253,0x0a},
    {0x325f,0x0c},
    {0x3273,0x01},
    {0x3301,0x30},
    {0x3304,0x30},
    {0x3306,0x70},
    {0x3308,0x10},
    {0x3309,0x50},
    {0x330b,0xf0},
    {0x330e,0x14},
    {0x3314,0x94},
    {0x331e,0x29},
    {0x331f,0x49},
    {0x3320,0x09},
    {0x334c,0x10},
    {0x3352,0x02},
    {0x3356,0x1f},
    {0x335e,0x02},
    {0x335f,0x04},
    {0x3363,0x00},
    {0x3364,0x1e},
    {0x3366,0x92},
    {0x336d,0x03},
    {0x337a,0x08},
    {0x337b,0x10},
    {0x337c,0x06},
    {0x337d,0x0a},
    {0x337f,0x2d},
    {0x3390,0x08},
    {0x3391,0x18},
    {0x3392,0x38},
    {0x3393,0x30},
    {0x3394,0x30},
    {0x3395,0x30},
    {0x3399,0xff},
    {0x33a2,0x08},
    {0x33a3,0x0c},
    {0x33e0,0xa0},
    {0x33e1,0x08},
    {0x33e2,0x00},
    {0x33e3,0x10},
    {0x33e4,0x10},
    {0x33e5,0x00},
    {0x33e6,0x10},
    {0x33e7,0x10},
    {0x33e8,0x00},
    {0x33e9,0x10},
    {0x33ea,0x16},
    {0x33eb,0x00},
    {0x33ec,0x10},
    {0x33ed,0x18},
    {0x33ee,0xa0},
    {0x33ef,0x08},
    {0x33f4,0x00},
    {0x33f5,0x10},
    {0x33f6,0x10},
    {0x33f7,0x00},
    {0x33f8,0x10},
    {0x33f9,0x10},
    {0x33fa,0x00},
    {0x33fb,0x10},
    {0x33fc,0x16},
    {0x33fd,0x00},
    {0x33fe,0x10},
    {0x33ff,0x18},
    {0x360f,0x05},
    {0x3622,0xee},
    {0x3625,0x0a},
    {0x3630,0xa8},
    {0x3631,0x80},
    {0x3633,0x44},
    {0x3634,0x34},
    {0x3635,0x60},
    {0x3636,0x20},
    {0x3637,0x11},
    {0x3638,0x2a},
    {0x363a,0x1f},
    {0x363b,0x03},
    {0x366e,0x04},
    {0x3670,0x4a},
    {0x3671,0xee},
    {0x3672,0x0e},
    {0x3673,0x0e},
    {0x3674,0x70},
    {0x3675,0x40},
    {0x3676,0x45},
    {0x367a,0x08},
    {0x367b,0x38},
    {0x367c,0x08},
    {0x367d,0x38},
    {0x3690,0x43},
    {0x3691,0x63},
    {0x3692,0x63},
    {0x3699,0x80},
    {0x369a,0x9f},
    {0x369b,0x9f},
    {0x369c,0x08},
    {0x369d,0x38},
    {0x36a2,0x08},
    {0x36a3,0x38},
    {0x36ea,0x3b},
    {0x36eb,0x16},
    {0x36ec,0x0e},
    {0x36ed,0x14},
    {0x36fa,0x36},
    {0x36fb,0x09},
    {0x36fc,0x00},
    {0x36fd,0x24},
    {0x3902,0xc5},
    {0x3905,0xd8},
    {0x3908,0x11},
    {0x391b,0x80},
    {0x391c,0x0f},
    {0x3933,0x28},
    {0x3934,0x20},
    {0x3940,0x6c},
    {0x3942,0x08},
    {0x3943,0x28},
    {0x3980,0x00},
    {0x3981,0x00},
    {0x3982,0x00},
    {0x3983,0x00},
    {0x3984,0x00},
    {0x3985,0x00},
    {0x3986,0x00},
    {0x3987,0x00},
    {0x3988,0x00},
    {0x3989,0x00},
    {0x398a,0x00},
    {0x398b,0x04},
    {0x398c,0x00},
    {0x398d,0x04},
    {0x398e,0x00},
    {0x398f,0x08},
    {0x3990,0x00},
    {0x3991,0x10},
    {0x3992,0x03},
    {0x3993,0xd8},
    {0x3994,0x03},
    {0x3995,0xe0},
    {0x3996,0x03},
    {0x3997,0xf0},
    {0x3998,0x03},
    {0x3999,0xf8},
    {0x399a,0x00},
    {0x399b,0x00},
    {0x399c,0x00},
    {0x399d,0x08},
    {0x399e,0x00},
    {0x399f,0x10},
    {0x39a0,0x00},
    {0x39a1,0x18},
    {0x39a2,0x00},
    {0x39a3,0x28},
    {0x39af,0x58},
    {0x39b5,0x30},
    {0x39b6,0x00},
    {0x39b7,0x34},
    {0x39b8,0x00},
    {0x39b9,0x00},
    {0x39ba,0x34},
    {0x39bb,0x00},
    {0x39bc,0x00},
    {0x39bd,0x00},
    {0x39be,0x00},
    {0x39bf,0x00},
    {0x39c0,0x00},
    {0x39c1,0x00},
    {0x39c5,0x21},
    {0x39c8,0x00},
    {0x39db,0x20},
    {0x39dc,0x00},
    {0x39de,0x20},
    {0x39df,0x00},
    {0x39e0,0x00},
    {0x39e1,0x00},
    {0x39e2,0x00},
    {0x39e3,0x00},
    {0x3e00,0x00},
    {0x3e01,0xc2},
    {0x3e02,0xa0},
    {0x3e03,0x0b},
    {0x3e06,0x00},
    {0x3e07,0x80},
    {0x3e08,0x03},
    {0x3e09,0x40},
    {0x3e14,0xb1},
    {0x3e25,0x03},
    {0x3e26,0x40},
    {0x4501,0xb4},
    {0x4509,0x20},
    {0x4800,0x64},
    {0x4818,0x00},
    {0x4819,0x30},
    {0x481a,0x00},
    {0x481b,0x0b},
    {0x481c,0x00},
    {0x481d,0xc8},
    {0x4821,0x02},
    {0x4822,0x00},
    {0x4823,0x03},
    {0x4828,0x00},
    {0x4829,0x02},
    {0x4837,0x3b},
    {0x5784,0x10},
    {0x5785,0x08},
    {0x5787,0x06},
    {0x5788,0x06},
    {0x5789,0x00},
    {0x578a,0x06},
    {0x578b,0x06},
    {0x578c,0x00},
    {0x5790,0x10},
    {0x5791,0x10},
    {0x5792,0x00},
    {0x5793,0x10},
    {0x5794,0x10},
    {0x5795,0x00},
    {0x57c4,0x10},
    {0x57c5,0x08},
    {0x57c7,0x06},
    {0x57c8,0x06},
    {0x57c9,0x00},
    {0x57ca,0x06},
    {0x57cb,0x06},
    {0x57cc,0x00},
    {0x57d0,0x10},
    {0x57d1,0x10},
    {0x57d2,0x00},
    {0x57d3,0x10},
    {0x57d4,0x10},
    {0x57d5,0x00},
    {0x5988,0x86},
    {0x598e,0x05},
    {0x598f,0x6c},
    {0x36e9,0x25},
    {0x36f9,0x54},
    //{0x0100,0x01},
};

static CAMERA_POWER_ACT_S s_stPowerUpAct[] = {
    {SNS_RESET, SNS_DOWN},
    {SNS_DELAY, 5},
    {SNS_PWDN, SNS_DOWN},
    {SNS_DELAY, 20},
    {SNS_RESET, SNS_UP},
    {SNS_DELAY, 5},
    {SNS_PWDN, SNS_UP},
    {SNS_DELAY, 2},
};

static CAMERA_POWER_ACT_S s_sPowerDownAct[] = {
    {SNS_RESET, SNS_DOWN},
    {SNS_DELAY, 10},
    {SNS_PWDN, SNS_DOWN},
};

/* hts:{0x320c,0x320d} * 2
 * vts:{0x320e,0x320f}
 */

static SNS_TYPE_ATTR_S s_astSnsAttr[] = {
#if 0
    {
        .enSnsType                  = SC4238_MIPI_1920_1080_30FPS_RAW10,
        .enPixelFormat              = PIX_FMT_RGB_BAYER_10BITS,
        .enRgbSeq                   = VISS_RGB_SEQ_BGGR,
        .stSize                     = {1920,1080},
        .u32ModuleClk               = 198000000,
        .u32Mclock                  = 27000000,
        .enWorkMode                 = VISS_WORK_MODE_1Chn,
        .enWdrMode                  = VISS_WDR_MODE_VC,

        .u32IspClk                  = 99000000,
        .u32IppuClk                 = 198000000,

        .u32Pclk                    = 134956800,
        .u32Vts                     = 1562,
        .u32Hts                     = 2880,
        .enIspWdrMode               = WDR_MODE_NONE,

        .u32FrameRate                = 30,
        .astRegCfgs[0].pstRegs      = s_aRaw1080p4lane30fps10bit,
        .astRegCfgs[0].u32RegsCnt   = ARRAY_SIZE(s_aRaw1080p4lane30fps10bit),

        .stDevCfg.stMcsiCfg.u32PhyFreq  = 3375001000,
        .stDevCfg.stMcsiCfg.enDlanes    = VISS_LANE_NUM_4Lane,
    },

    {
        .enSnsType                  = SC4238_MIPI_1920_1080_2TO1_30FPS_RAW10,
        .enPixelFormat              = PIX_FMT_RGB_BAYER_10BITS,
        .enRgbSeq                   = VISS_RGB_SEQ_BGGR,
        .stSize                     = {1920,1080},
        .u32ModuleClk               = 198000000,
        .u32Mclock                  = 27000000,
        .enWorkMode                 = VISS_WORK_MODE_2Chn,
        .enWdrMode                  = VISS_WDR_MODE_VC,

        .u32IspClk                  = 99000000,
        .u32IppuClk                 = 198000000,

        .u32Pclk                    = 575856000,
        .u32Vts                     = 3096,
        .u32Hts                     = 3100,
        .enIspWdrMode               = WDR_MODE_2TO1_FRAME,
        /* {0x3e23,0x3e24} */
        .u32MaxShortExp             = 186,

        .u32FrameRate                = 30,
        .astRegCfgs[0].pstRegs      = s_aRaw1080p4lane30fps10bit2fHDR,
        .astRegCfgs[0].u32RegsCnt   = ARRAY_SIZE(s_aRaw1080p4lane30fps10bit2fHDR),

        .stDevCfg.stMcsiCfg.u32PhyFreq  = 720000000,
        .stDevCfg.stMcsiCfg.enDlanes    = VISS_LANE_NUM_4Lane,
    },
#endif
    {
        .enSnsType                  = SC4238_MIPI_2688_1520_25FPS_RAW12,
        .enPixelFormat              = PIX_FMT_RGB_BAYER_12BITS,
        .enRgbSeq                   = VISS_RGB_SEQ_BGGR,
        .stSize                     = {2688, 1520},
        .u32ModuleClk               = 198000000,
        .u32Mclock                  = 27000000,
        .enWorkMode                 = VISS_WORK_MODE_1Chn,
        .enWdrMode                  = VISS_WDR_MODE_VC,

        .u32IspClk                  = 184000000,
        .u32IppuClk                 = 276000000,

        .u32Pclk                    = 134956800,
        .u32Vts                     = 1874,
        .u32Hts                     = 2880,
        .enIspWdrMode               = WDR_MODE_NONE,

        .u32FrameRate               = 25,
        .astRegCfgs[0].pstRegs      = s_aRaw2688X1520p4lane30fps12bit,
        .astRegCfgs[0].u32RegsCnt   = ARRAY_SIZE(s_aRaw2688X1520p4lane30fps12bit),

        .stDevCfg.stMcsiCfg.u32PhyFreq  = 405000000,
        .stDevCfg.stMcsiCfg.enDlanes    = VISS_LANE_NUM_4Lane,
    },
    {
        .enSnsType                  = SC4238_MIPI_2688_1520_30FPS_RAW12,
        .enPixelFormat              = PIX_FMT_RGB_BAYER_12BITS,
        .enRgbSeq                   = VISS_RGB_SEQ_BGGR,
        .stSize                     = {2688, 1520},
        .u32ModuleClk               = 198000000,
        .u32Mclock                  = 27000000,
        .enWorkMode                 = VISS_WORK_MODE_1Chn,
        .enWdrMode                  = VISS_WDR_MODE_VC,

        .u32IspClk                  = 184000000,
        .u32IppuClk                 = 276000000,

        .u32Pclk                    = 134956800,
        .u32Vts                     = 1562,
        .u32Hts                     = 2880,
        .enIspWdrMode               = WDR_MODE_NONE,

        .u32FrameRate                = 30,
        .astRegCfgs[0].pstRegs      = s_aRaw2688X1520p4lane30fps12bit,
        .astRegCfgs[0].u32RegsCnt   = ARRAY_SIZE(s_aRaw2688X1520p4lane30fps12bit),

        .stDevCfg.stMcsiCfg.u32PhyFreq  = 405000000,
        .stDevCfg.stMcsiCfg.enDlanes    = VISS_LANE_NUM_4Lane,
    },

    {
        .enSnsType                  = SC4238_MIPI_2688_1520_2TO1_25FPS_RAW10,
        .enPixelFormat              = PIX_FMT_RGB_BAYER_10BITS,
        .enRgbSeq                   = VISS_RGB_SEQ_BGGR,
        .stSize                     = {2688, 1520},
        .u32ModuleClk               = 297000000,
        .u32Mclock                  = 27000000,
        .enWorkMode                 = VISS_WORK_MODE_2Chn,
        .enWdrMode                  = VISS_WDR_MODE_VC,

        .u32IspClk                  = 166000000,
        .u32IppuClk                 = 272000000,
        .u32Pclk                    = 575856000,
        .u32Vts                     = 3715,
        .u32Hts                     = 3100,
        .u32MaxShortExp             = 186,
        .enIspWdrMode               = WDR_MODE_2TO1_FRAME,

        .u32FrameRate                = 25,
        .astRegCfgs[0].pstRegs      = s_aRaw2688X1520p4lane30fps10bit2fHDR,
        .astRegCfgs[0].u32RegsCnt   = ARRAY_SIZE(s_aRaw2688X1520p4lane30fps10bit2fHDR),

        .stDevCfg.stMcsiCfg.u32PhyFreq  = 720000000,
        .stDevCfg.stMcsiCfg.enDlanes    = VISS_LANE_NUM_4Lane,
    },
    {
        .enSnsType                  = SC4238_MIPI_2688_1520_2TO1_30FPS_RAW10,
        .enPixelFormat              = PIX_FMT_RGB_BAYER_10BITS,
        .enRgbSeq                   = VISS_RGB_SEQ_BGGR,
        .stSize                     = {2688, 1520},
        .u32ModuleClk               = 297000000,
        .u32Mclock                  = 27000000,
        .enWorkMode                 = VISS_WORK_MODE_2Chn,
        .enWdrMode                  = VISS_WDR_MODE_VC,

        .u32IspClk                  = 166000000,
        .u32IppuClk                 = 272000000,
        .u32Pclk                    = 575856000,
        .u32Vts                     = 3096,
        .u32Hts                     = 3100,
        /* {0x3e23,0x3e24} */
        .u32MaxShortExp             = 186,
        .enIspWdrMode               = WDR_MODE_2TO1_FRAME,

        .u32FrameRate                = 30,
        .astRegCfgs[0].pstRegs      = s_aRaw2688X1520p4lane30fps10bit2fHDR,
        .astRegCfgs[0].u32RegsCnt   = ARRAY_SIZE(s_aRaw2688X1520p4lane30fps10bit2fHDR),

        .stDevCfg.stMcsiCfg.u32PhyFreq  = 720000000,
        .stDevCfg.stMcsiCfg.enDlanes    = VISS_LANE_NUM_4Lane,
    },
};

static int CAMERA_SetI2cInfo(VISS_DEV dev)
{
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    if (pstSnsState->stI2cInfo.fd > 0) {
        return EI_SUCCESS;
    }

    pstSnsState->stI2cInfo.u8RegBits = 16;
    pstSnsState->stI2cInfo.u8ValBits = 8;
    pstSnsState->stI2cInfo.u16I2cBusNum = 4;
    pstSnsState->stI2cInfo.u16I2cDevAddr = 0x30;
    pstSnsState->pcName = SNS_NAME;

    return EI_SUCCESS;
}
static EI_S32 CAMERA_Detect(VISS_DEV VissDev)
{
    EI_U8 u8Tmp[2];
    EI_S32 s32Ret = EI_SUCCESS;
    EI_U16 u16Id;
    SNS_STATE_S *pstSnsState = EI_NULL;
    I2C_INFO_S *pstI2cInfo = EI_NULL;

    SNS_GET_CTX(VissDev, pstSnsState);

    pstI2cInfo = &pstSnsState->stI2cInfo;

    CAMERA_CHECK_POINTER(pstI2cInfo->pfnReadReg);
    s32Ret = pstI2cInfo->pfnReadReg(pstSnsState, 0x3107, &u8Tmp[0]);
    if (s32Ret != 0) {
        PRT_VISS_ERR("%s tmp[0]=%x\n", SNS_NAME, u8Tmp[0]);
        return s32Ret;
    }
    s32Ret = pstI2cInfo->pfnReadReg(pstSnsState, 0x3108, &u8Tmp[1]);
    if (s32Ret != 0) {
        PRT_VISS_ERR("%s tmp[0]=%x,tmp[1]=%x\n", SNS_NAME, u8Tmp[0], u8Tmp[1]);
        return s32Ret;
    }
    u16Id = (u8Tmp[0] << 8) | u8Tmp[1];
    PRT_VISS_INFO("%s id: 0x%04x\n", SNS_NAME, u16Id);

    if (u16Id != 0x4235) {
        PRT_VISS_ERR("%s ID wrong! (0x%04x != 0x4235)\n", SNS_NAME, u16Id);
        return EI_FAILURE;
    }

    return EI_SUCCESS;
}

static EI_S32 CAMERA_Stream(VISS_DEV dev, EI_BOOL bOn)
{
    SNS_STATE_S *pstSnsState = EI_NULL;
    EI_S32 s32Ret = EI_SUCCESS;
    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);
    PRT_VISS_INFO("%s ----CAMERA_Stream----%d\n", SNS_NAME, bOn);

    if (bOn) {
        s32Ret = pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x0100, 0x01);
        if (s32Ret != EI_SUCCESS) {
            PRT_VISS_ERR("CAMERA_Stream err*******%d\n", bOn);
        }
    } else {
        s32Ret = pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x0100, 0x00);
        if (s32Ret != EI_SUCCESS) {
            PRT_VISS_ERR("CAMERA_Stream err*******%d\n", bOn);
        }
    }
    return s32Ret;

}

/* The following functions can be modified as needed */

static int CAMERA_I2cInit(VISS_DEV dev)
{
    SNS_STATE_S *pstSnsState = EI_NULL;
    int ret = EI_SUCCESS;

    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    ret = CAMERA_SetI2cInfo(dev);
    CAMERA_CHECK_SUCCESS(ret);

    ret = CAMERA_I2C_Reg_Ops(&pstSnsState->stI2cInfo);
    CAMERA_CHECK_SUCCESS(ret);

    return EI_SUCCESS;
}

static int CAMERA_I2cExit(VISS_DEV dev)
{
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    return EI_SUCCESS;
}

static EI_S32 CAMERA_PowerUp(VISS_DEV VissDev)
{
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(VissDev, pstSnsState);

    MI_VISS_SnsPower(VissDev, 0xa0000000);
    CAMERA_SensorPowerUp(VissDev, pstSnsState);

    return 0;
}

static EI_S32 CAMERA_PowerDown(VISS_DEV VissDev)
{
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(VissDev, pstSnsState);

    MI_VISS_SnsPower(VissDev, 0x00000000);

    CAMERA_SensorPowerDown(VissDev, pstSnsState);

    return 0;
}

static EI_S32 CAMERA_MirrorFlip(VISS_DEV VissDev)
{
    SNS_STATE_S *pstSnsState = EI_NULL;
    I2C_INFO_S *pstI2cInfo = EI_NULL;
    EI_S32 s32Ret = EI_SUCCESS;
    EI_U32 u32Tmp = 0;

    SNS_GET_CTX(VissDev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    pstI2cInfo = &pstSnsState->stI2cInfo;

    PRT_VISS_INFO("%s set mirror[%d] flip[%d] \n", SNS_NAME,
        pstSnsState->u32SnsMirror, pstSnsState->u32SnsFlip);

    if (!pstSnsState->u32SnsMirror && !pstSnsState->u32SnsFlip) {
        s32Ret = pstI2cInfo->pfnWriteReg(pstSnsState, 0x3221, (u32Tmp & 0x99 ) | 0x00);
        if (s32Ret != 0) {
            PRT_VISS_ERR("%s pfnWriteReg error\n", SNS_NAME);
            return s32Ret;
        }
        return s32Ret;
    }

    /* sensor flip & mirror */
    pstI2cInfo->pfnReadReg(pstSnsState, 0x3221, &u32Tmp);
    if (s32Ret != 0) {
        PRT_VISS_ERR("%s pfnReadReg error\n", SNS_NAME);
        return s32Ret;
    }

    if (pstSnsState->u32SnsMirror) {
        s32Ret = pstI2cInfo->pfnWriteReg(pstSnsState, 0x3221, (u32Tmp & 0xf9 ) | 0x06);
    } else {
        s32Ret = pstI2cInfo->pfnWriteReg(pstSnsState, 0x3221, (u32Tmp & 0xf9 ));
    }
    if (s32Ret != 0) {
        PRT_VISS_ERR("%s pfnWriteReg error\n", SNS_NAME);
        return s32Ret;
    }

    pstI2cInfo->pfnReadReg(pstSnsState, 0x3221, &u32Tmp);
    if (s32Ret != 0) {
        PRT_VISS_ERR("%s pfnReadReg error\n", SNS_NAME);
        return s32Ret;
    }

    if (pstSnsState->u32SnsFlip) {
        s32Ret = pstI2cInfo->pfnWriteReg(pstSnsState, 0x3221, (u32Tmp & 0x9f ) | 0x60);
    } else {
        s32Ret = pstI2cInfo->pfnWriteReg(pstSnsState, 0x3221, (u32Tmp & 0x9f ));
    }
    if (s32Ret != 0) {
        PRT_VISS_ERR("%s pfnWriteReg error\n", SNS_NAME);
        return s32Ret;
    }

    return s32Ret;
}

static EI_S32 CAMERA_SetGain(ISP_DEV dev, EI_FLOAT fGain);
static EI_S32 CAMERA_SetExpTime(ISP_DEV dev, EI_FLOAT *afIntTime);

static EI_S32 CAMERA_Init(VISS_DEV dev)
{
    EI_U32 j;
    const SNS_TYPE_ATTR_S *pstSnsType;
    SNS_STATE_S *pstSnsState = EI_NULL;
    EI_S32 s32Ret;
    I2C_INFO_S *pstI2cInfo = EI_NULL;

    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    pstI2cInfo = &pstSnsState->stI2cInfo;

    pstSnsType = pstSnsState->pstSnsAttr;
    for (j = 0; j < MAX_COF; j++) {
        s32Ret = pstSnsState->stI2cInfo.pfnwriteRegList(pstSnsState,
                pstSnsType->astRegCfgs[j].pstRegs, pstSnsType->astRegCfgs[j].u32RegsCnt);
        if (s32Ret != EI_SUCCESS) {
            PRT_VISS_ERR("%s writeRegList err\n", SNS_NAME);
            return s32Ret;
        }
    }

    if(pstSnsType->enSnsType == SC4238_MIPI_2688_1520_25FPS_RAW12) {
        s32Ret += pstI2cInfo->pfnWriteReg(pstSnsState, 0x320e, 0x07);
        s32Ret += pstI2cInfo->pfnWriteReg(pstSnsState, 0x320f, 0x52);
        if (s32Ret != 0) {
            PRT_VISS_ERR("CAMERA_Init error\n");
            return s32Ret;
        }
    }

    if(pstSnsType->enSnsType == SC4238_MIPI_2688_1520_2TO1_25FPS_RAW10) {
        s32Ret += pstI2cInfo->pfnWriteReg(pstSnsState, 0x320e, 0x0e);
        s32Ret += pstI2cInfo->pfnWriteReg(pstSnsState, 0x320f, 0x83);
        if (s32Ret != 0) {
            PRT_VISS_ERR("CAMERA_Init error\n");
            return s32Ret;
        }

        s32Ret += pstI2cInfo->pfnWriteReg(pstSnsState, 0x3235, 0x1d);/* {0x3235, 0x3236} = {0x320e, 0x320f}*2 -1 */
        s32Ret += pstI2cInfo->pfnWriteReg(pstSnsState, 0x3236, 0x05);
        if (s32Ret != 0) {
            PRT_VISS_ERR("CAMERA_Init error\n");
            return s32Ret;
        }
    }

    if ((pstSnsState->afIntTime[0] > 0.000001) && (pstSnsState->fGain >= 1.0)) {
        CAMERA_SetExpTime(pstSnsState->IspDev, pstSnsState->afIntTime);
        CAMERA_SetGain(pstSnsState->IspDev, pstSnsState->fGain);
    }

    CAMERA_MirrorFlip(dev);

    PRT_VISS_INFO("%s writeRegList success\n", SNS_NAME);

    return s32Ret;
}

static void CAMERA_Exit(VISS_DEV dev)
{
    CAMERA_I2cExit(dev);

    return;
}

static EI_S32 CAMERA_SetImageMode(VISS_DEV dev, SNS_TYPE_E enSnsType)
{
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    pstSnsState->enSnsType = enSnsType;
    pstSnsState->bSyncInit = EI_FALSE;

    return EI_SUCCESS;
}

static EI_S32 CAMERA_EnumSnstype(VISS_DEV VissDev, EI_U32 u32Index, SNS_TYPE_E *peSnstype)
{
    const SNS_TYPE_ATTR_S *pstSnsType;

    if (u32Index >= ARRAY_SIZE(s_astSnsAttr))
        return EN_ERR_NO_FOUND;

    pstSnsType = &s_astSnsAttr[u32Index];

    *peSnstype = pstSnsType->enSnsType;

    return EI_SUCCESS;
}

static EI_S32 CAMERA_SetFrameRate(VISS_DEV VissDev, EI_FLOAT f32Fps)
{
    I2C_INFO_S *pstI2cInfo = EI_NULL;
    SNS_STATE_S *pstSnsState = EI_NULL;
    EI_S32 s32Ret = EI_SUCCESS;
    EI_U32 u32Pclk, u32Hts, u32Vts;

    SNS_GET_CTX(VissDev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    pstI2cInfo = &pstSnsState->stI2cInfo;
    u32Pclk = pstSnsState->pstSnsAttr->u32Pclk;
    u32Hts = pstSnsState->pstSnsAttr->u32Hts;

    if (pstSnsState->pstSnsAttr->enIspWdrMode == WDR_MODE_NONE) {
        if (pstSnsState->pstSnsAttr->u32FrameRate < f32Fps || 1 > f32Fps) {
            cprintf("1 <= set fps <= %d, set fps: %f\n", pstSnsState->pstSnsAttr->u32FrameRate, f32Fps);
            f32Fps = pstSnsState->pstSnsAttr->u32FrameRate;
        }

        u32Vts = u32Pclk / u32Hts / f32Fps;

        s32Ret += pstI2cInfo->pfnWriteReg(pstSnsState, 0x320e, u32Vts >> 8);
        s32Ret += pstI2cInfo->pfnWriteReg(pstSnsState, 0x320f, u32Vts);

        if (s32Ret != 0) {
            cprintf("CAMERA_Init error\n");
            return s32Ret;
        }
    } else if (pstSnsState->pstSnsAttr->enIspWdrMode == WDR_MODE_2TO1_FRAME) {
        if (pstSnsState->pstSnsAttr->u32FrameRate < f32Fps || 1 > f32Fps) {
            cprintf("1 <= set fps <= %d, set fps: %f\n", pstSnsState->pstSnsAttr->u32FrameRate, f32Fps);
            f32Fps = pstSnsState->pstSnsAttr->u32FrameRate;
        }

        u32Vts = u32Pclk / u32Hts / f32Fps;

        s32Ret += pstI2cInfo->pfnWriteReg(pstSnsState, 0x320e, u32Vts >> 8);
        s32Ret += pstI2cInfo->pfnWriteReg(pstSnsState, 0x320f, u32Vts);

        if (s32Ret != 0) {
            cprintf("CAMERA_Init error\n");
            return s32Ret;
        }
    } else {
        return EN_ERR_NOT_SUPPORT;
    }
    pstSnsState->pstSnsAttr->u32Vts = u32Vts;

    return EI_SUCCESS;
}

static EI_S32 CAMERA_InitSensorExpFunction(SENSOR_EXP_FUNC_S *pstSensorExpFunc)
{
    CAMERA_CHECK_POINTER(pstSensorExpFunc);

    memset(pstSensorExpFunc, 0, sizeof(SENSOR_EXP_FUNC_S));

    pstSensorExpFunc->pfnSensorPowerUp  = CAMERA_PowerUp;
    pstSensorExpFunc->pfnSensorPowerDown = CAMERA_PowerDown;
    pstSensorExpFunc->pfnSensorDetect   = CAMERA_Detect;
    pstSensorExpFunc->pfnSensorInit     = CAMERA_Init;
    pstSensorExpFunc->pfnSensorStream   = CAMERA_Stream;
    pstSensorExpFunc->pfnSensorExit     = CAMERA_Exit;
    pstSensorExpFunc->pfnSensorSetImageMode   = CAMERA_SetImageMode;
    pstSensorExpFunc->pfnSensorEnumSnstype   = CAMERA_EnumSnstype;
    pstSensorExpFunc->pfnSensorSetFrameRate   = CAMERA_SetFrameRate;
    pstSensorExpFunc->pfnSensorSetMirrorFlip = CAMERA_MirrorFlip;

    return EI_SUCCESS;
}

static EI_S32 CAMERA_GetAeDefault(ISP_DEV dev, AE_SENSOR_DEFAULT_S *pstAeSnsDft)
{
    CAMERA_CHECK_POINTER(pstAeSnsDft);

    return EI_SUCCESS;
}

static EI_S32 CAMERA_SetFps(ISP_DEV dev, EI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft)
{
    VISS_DEV Dev;

    SNS_GET_ISP_TO_VISS(dev, Dev);

    CAMERA_CHECK_POINTER(pstAeSnsDft);

    return CAMERA_SetFrameRate(Dev, f32Fps);
}

static EI_S32 CAMERA_SetExpTime(ISP_DEV dev, EI_FLOAT *afIntTime)
{
    SNS_STATE_S *pstSnsState = EI_NULL;
    EI_S32 s32Ret = EI_SUCCESS;
    EI_U32 u32Pclk, u32Hts, u32Vts;
    EI_U32 shutter_time;
    EI_U32 lexp, mexp;
    VISS_DEV Dev;
    EI_U32 u32MaxShortExp;

    SNS_GET_ISP_TO_VISS(dev, Dev);

    SNS_GET_CTX(Dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);
    CAMERA_CHECK_POINTER(afIntTime);
    pstSnsState->afIntTime[0] = afIntTime[0];
    pstSnsState->afIntTime[1] = afIntTime[1];
    pstSnsState->afIntTime[2] = afIntTime[2];
    pstSnsState->afIntTime[3] = afIntTime[3];
    pstSnsState->IspDev = dev;
    CAMERA_CHECK_POWERON(pstSnsState);

    u32Pclk = pstSnsState->pstSnsAttr->u32Pclk;
    u32Hts = pstSnsState->pstSnsAttr->u32Hts;
    u32Vts = pstSnsState->pstSnsAttr->u32Vts;

    if ((u32Pclk == 0) || (u32Hts == 0) || (u32Vts == 0)) {
        PRT_VISS_ERR("error! u32Pclk %d, u32Hts %d, u32Vts %d\n", u32Pclk, u32Hts, u32Vts);
        return EI_FAILURE;
    }

    /* afIntTime[0] long/medium/short/vshort exptime (s) */
    shutter_time = 2 * afIntTime[0] * u32Pclk / u32Hts;
    if (shutter_time < 3)
        shutter_time = 3;

    //printf("exp_time: %d, %f(s)!\n", shutter_time, afIntTime[0]);

    if (pstSnsState->pstSnsAttr->enIspWdrMode == WDR_MODE_NONE) {
        if (shutter_time > (2 * (u32Vts - 10)))
            shutter_time = 2 * (u32Vts - 10);

        s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3e00, (shutter_time >> 12) & 0x0f);
        s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3e01, (shutter_time >> 4) & 0xff);
        s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3e02, (shutter_time << 4) & 0xf0);

        if (s32Ret != EI_SUCCESS) {
            PRT_VISS_ERR("\n");
        }
    } else if (pstSnsState->pstSnsAttr->enIspWdrMode == WDR_MODE_2TO1_FRAME) {
        u32MaxShortExp = pstSnsState->pstSnsAttr->u32MaxShortExp;

        if (afIntTime[1] < 1)
            afIntTime[1] = 8;

        if (shutter_time < 5)
            shutter_time = 5;

        if (shutter_time > 2 * (u32Vts - u32MaxShortExp -9))
            lexp = 2 * (u32Vts - u32MaxShortExp -9);
        else
            lexp = shutter_time;

        mexp = shutter_time / afIntTime[1];

        if (mexp < 5)
            mexp = 5;

        if (mexp > 2 * (u32MaxShortExp - 8))
            mexp = 2 * (u32MaxShortExp - 8);

        lexp = mexp * afIntTime[1];

        //printf("exp_time: %d, %d\n", lexp, mexp);

        s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3e00, (lexp >> 12) & 0x0f);
        s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3e01, (lexp >> 4) & 0xff);
        s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3e02, (lexp << 4) & 0xf0);

        s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3e04, (mexp >> 4) & 0xff);
        s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3e05, (mexp << 4) & 0xf0);

        if (s32Ret != EI_SUCCESS) {
            PRT_VISS_ERR("\n");
        }

        shutter_time = lexp;
    }

    afIntTime[0] = (EI_FLOAT)(shutter_time / 2) * u32Hts / u32Pclk;
    if (afIntTime[0] < 0.00001) {
        PRT_VISS_WARN("Warning! afIntTime[0] < 0.00001, now force 0.00001 \n");
        afIntTime[0] = 0.00001;
    }

    return s32Ret;
}

static EI_S32 CAMERA_SetGain(ISP_DEV dev, EI_FLOAT fGain)
{
    SNS_STATE_S *pstSnsState = EI_NULL;
    EI_S32 s32Ret = EI_SUCCESS;
    EI_U32 again_fine, dgain_fine;
    EI_U32 again = 0, dgain = 0;
    EI_U32 gain;

    VISS_DEV Dev;

    SNS_GET_ISP_TO_VISS(dev, Dev);

    SNS_GET_CTX(Dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);
    pstSnsState->fGain = fGain;
    CAMERA_CHECK_POWERON(pstSnsState);

    if (fGain < 1)
        fGain = 1;

    if (fGain > 16 * 32)
        fGain = 16 * 32;

    gain = fGain * 1024;

    if (gain < 2 * 1024) {
        again = 3;
        again_fine = gain >> 4;
        dgain = 0;
        dgain_fine = (gain * 8 / again_fine);
    } else if (gain <  4 * 1024) {
        again = 7;
        again_fine = gain >> 5;
        dgain = 0;
        dgain_fine = (gain * 4 / again_fine);
    } else if (gain < 8 * 1024) {
        again = 0xf;
        again_fine = gain >> 6;
        dgain = 0;
        dgain_fine = (gain * 2 / again_fine);
    } else if (gain <= 15.875 * 1024) {
        again = 0x1f;
        again_fine = gain >> 7;
        dgain = 0;
        dgain_fine = (gain / again_fine);
    } else if (gain < 31.75 * 1024) {
        again = 0x1f;
        again_fine = 0x7f;
        dgain = 0;
        dgain_fine = gain / 127;
    } else if (gain < 63.5 * 1024) {
        again = 0x1f;
        again_fine = 0x7f;
        dgain = 1;
        dgain_fine = gain / 254;
    } else if (gain < 127 * 1024) {
        again = 0x1f;
        again_fine = 0x7f;
        dgain = 3;
        dgain_fine = gain / 508;
    } else if (gain < 254 * 1024) {
        again = 0x1f;
        again_fine = 0x7f;
        dgain = 7;
        dgain_fine = gain / 1016;
    } else if (gain <= 15.875 * 31.50 * 1024) {
        again = 0x1f;
        again_fine = 0x7f;
        dgain = 0xF;
        dgain_fine = gain / 2032;
    } else {
        again = 0x1f;
        again_fine = 0x7f;
        dgain = 0xF;
        dgain_fine = 254;
    }

    s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3e07, dgain_fine);
    s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3e06, dgain);
    s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3e09, again_fine);
    s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3e08, again);

    if (pstSnsState->pstSnsAttr->enIspWdrMode == WDR_MODE_2TO1_FRAME) {
        s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3e13, again_fine);
        s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3e12, again);
        s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3e11, dgain_fine);
        s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3e10, dgain);
    }

    if (s32Ret != EI_SUCCESS) {
        PRT_VISS_ERR("\n");
    }

    return s32Ret;
}

static EI_S32 CAMERA_InitAeExpFunction(AE_SENSOR_EXP_FUNC_S *pstExpFuncs)
{
    CAMERA_CHECK_POINTER(pstExpFuncs);

    memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S));

    pstExpFuncs->pfnGetAeDefault    = CAMERA_GetAeDefault;
    pstExpFuncs->pfnSetFps          = CAMERA_SetFps;
    pstExpFuncs->pfnSetExpTime      = CAMERA_SetExpTime;
    pstExpFuncs->pfnSetGain         = CAMERA_SetGain;

    return EI_SUCCESS;
}

static EI_S32 CAMERA_GetAwbDefault(ISP_DEV dev, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft)
{
    CAMERA_CHECK_POINTER(pstAwbSnsDft);

    return EI_SUCCESS;
}

static EI_S32 CAMERA_InitAwbExpFunction(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs)
{
    CAMERA_CHECK_POINTER(pstExpFuncs);

    memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S));
    pstExpFuncs->pfnGetAwbDefault = CAMERA_GetAwbDefault;

    return EI_SUCCESS;
}

/****************************************************************************
 * callback structure                                                       *
 ****************************************************************************/

static EI_S32 CAMERA_CtxInit(VISS_DEV dev)
{
    SNS_STATE_S *pastSnsStateCtx = EI_NULL;

    SNS_GET_CTX(dev, pastSnsStateCtx);

    CAMERA_CHECK_POINTER(pastSnsStateCtx);

    memset(pastSnsStateCtx, 0, sizeof(SNS_STATE_S));

    pastSnsStateCtx->pstPowerUpAct      = s_stPowerUpAct;
    pastSnsStateCtx->pstPowerDownAct    = s_sPowerDownAct;
    pastSnsStateCtx->u8PwrUpActs        = ARRAY_SIZE(s_stPowerUpAct);
    pastSnsStateCtx->u8PwrDnActs        = ARRAY_SIZE(s_sPowerDownAct);

    return EI_SUCCESS;
}

static EI_VOID CAMERA_CtxExit(VISS_DEV dev)
{
    return ;
}

static EI_S32 CAMERA_RegisterVissCallback(VISS_DEV dev, SNS_TYPE_E enType)
{
    EI_S32 s32Ret;
    SENSOR_S stSns = {0};
    EI_U32 i;
    SNS_STATE_S *pstSnsState = EI_NULL;

    s32Ret = CAMERA_CtxInit(dev);
    if (EI_SUCCESS != s32Ret) {
        return EI_FAILURE;
    }

    SNS_GET_CTX(dev, pstSnsState);

    for (i = 0; i < ARRAY_SIZE(s_astSnsAttr); i++) {
        if (enType == s_astSnsAttr[i].enSnsType) {
            pstSnsState->pstSnsAttr = &s_astSnsAttr[i];
            break;
        }
    }

    pstSnsState->enSnsType = enType;
    pstSnsState->Dev = dev;

    if (i >= ARRAY_SIZE(s_astSnsAttr)) {
        PRT_VISS_ERR("%s does not support this chn configuration", SNS_NAME);
        return EI_FAILURE;
    }

    s32Ret = CAMERA_I2cInit(dev);
    if (EI_SUCCESS != s32Ret) {
        return EI_FAILURE;
    }

    stSns.stSnsAttrInfo.eSensorId = SNS_ID;
    stSns.stSnsAttrInfo.enDevType = DEV_TYPE;
    stSns.stSnsAttrInfo.pstSns = pstSnsState;

    s32Ret  = CAMERA_InitSensorExpFunction(&stSns.stSnsAttrInfo.stSnsExp);
    s32Ret |= VISS_SensorRegCallBack(dev, &stSns);
    if (EI_SUCCESS != s32Ret) {
        PRT_VISS_ERR("%s sensor register callback function failed!\n", SNS_NAME);
        return s32Ret;
    }

    s32Ret = CAMERA_OpenI2c(pstSnsState);
    CAMERA_CHECK_SUCCESS(s32Ret);

    return EI_SUCCESS;
}

static EI_S32 CAMERA_UnregisterVissCallback(VISS_DEV dev)
{
    EI_S32 s32Ret;
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(dev, pstSnsState);

    s32Ret = CAMERA_ExitI2c(pstSnsState);
    CAMERA_CHECK_SUCCESS(s32Ret);

    s32Ret = VISS_SensorUnRegCallBack(dev, SNS_ID);
    if (EI_SUCCESS != s32Ret) {
        PRT_VISS_ERR("%s sensor unregister callback function failed!\n", SNS_NAME);
        return s32Ret;
    }

    CAMERA_CtxExit(dev);

    return EI_SUCCESS;
}

static EI_S32 CAMERA_RegisterIspCallback(VISS_DEV Dev, ISP_DEV dev, ISP_3ALIB_S *pstAeLib, ISP_3ALIB_S *pstAwbLib)
{
    EI_S32 s32Ret;
    AE_SENSOR_REGISTER_S  stAeRegister;
    AWB_SENSOR_REGISTER_S stAwbRegister;

    CAMERA_CHECK_POINTER(pstAeLib);
    CAMERA_CHECK_POINTER(pstAwbLib);

    SNS_SET_ISP_TO_VISS(dev, Dev);

    stAeRegister.SnsId = SNS_ID;
    stAwbRegister.SnsId = SNS_ID;

    s32Ret  = CAMERA_InitAeExpFunction(&stAeRegister.stSnsExp);
    s32Ret |= EI_MI_AE_SensorRegCallBack(dev, pstAeLib, &stAeRegister);

    if (EI_SUCCESS != s32Ret) {
        EI_TRACE_ISP(EI_DBG_ERR, "%s register callback function to ae lib failed!\n", SNS_NAME);
        return s32Ret;
    }

    s32Ret  = CAMERA_InitAwbExpFunction(&stAwbRegister.stSnsExp);
    s32Ret |= EI_MI_AWB_SensorRegCallBack(dev, pstAwbLib, &stAwbRegister);

    if (EI_SUCCESS != s32Ret) {
        EI_TRACE_ISP(EI_DBG_ERR, "%s register callback function to awb lib failed!\n", SNS_NAME);
        return s32Ret;
    }

    return EI_SUCCESS;
}

static EI_S32 CAMERA_UnregisterIspCallback(ISP_DEV dev, ISP_3ALIB_S *pstAeLib, ISP_3ALIB_S *pstAwbLib)
{
    EI_S32 s32Ret;

    CAMERA_CHECK_POINTER(pstAeLib);
    CAMERA_CHECK_POINTER(pstAwbLib);

    s32Ret = EI_MI_AE_SensorUnRegCallBack(dev, pstAeLib, SNS_ID);
    if (EI_SUCCESS != s32Ret) {
        EI_TRACE_ISP(EI_DBG_ERR, "%s unregister callback function to ae lib failed!\n", SNS_NAME);
        return s32Ret;
    }

    s32Ret = EI_MI_AWB_SensorUnRegCallBack(dev, pstAwbLib, SNS_ID);
    if (EI_SUCCESS != s32Ret) {
        EI_TRACE_ISP(EI_DBG_ERR, "%s unregister callback function to awb lib failed!\n", SNS_NAME);
        return s32Ret;
    }

    return EI_SUCCESS;
}

static EI_S32 CAMERA_GetVissDevAttrBySns(SNS_TYPE_E enType,
    VISS_DEV_ATTR_S *pstVissDevAttr)
{
    EI_U32 i;
    const SNS_TYPE_ATTR_S *pstSnsType;

    for (i = 0; i < ARRAY_SIZE(s_astSnsAttr); i++) {
        if (enType == s_astSnsAttr[i].enSnsType) {
            pstSnsType = &s_astSnsAttr[i];
            pstVissDevAttr->stSize          = pstSnsType->stSize;
            pstVissDevAttr->enWorkMode      = pstSnsType->enWorkMode;
            pstVissDevAttr->mClock          = pstSnsType->u32Mclock;
            pstVissDevAttr->enPixelFormat   = pstSnsType->enPixelFormat;
            pstVissDevAttr->enWdrMode       = pstSnsType->enWdrMode;
            pstVissDevAttr->enIspWdrMode    = pstSnsType->enIspWdrMode;
            pstVissDevAttr->enRgbSeq        = pstSnsType->enRgbSeq;
            pstVissDevAttr->u32ModuleClk    = pstSnsType->u32ModuleClk;
            pstVissDevAttr->u32Fps          = pstSnsType->u32FrameRate;
            pstVissDevAttr->u32IspClk       = pstSnsType->u32IspClk;
            pstVissDevAttr->u32IppuClk      = pstSnsType->u32IppuClk;
            pstVissDevAttr->pcSnsName       = SNS_NAME;
            pstVissDevAttr->stDevCfg        = pstSnsType->stDevCfg;
            return EI_SUCCESS;
        }
    }

    PRT_VISS_ERR("%s does not support this dev configuration", SNS_NAME);

    return EI_FAILURE;
}

static EI_S32 CAMERA_GetVissChnAttrBySns(SNS_TYPE_E enType,
    VISS_CHN_ATTR_S *pstVissChnAttr)
{
    EI_U32 i;
    const SNS_TYPE_ATTR_S *pstSnsType;

    for (i = 0; i < ARRAY_SIZE(s_astSnsAttr); i++) {
        if (enType == s_astSnsAttr[i].enSnsType) {
            pstSnsType = &s_astSnsAttr[i];
            pstVissChnAttr->stSize          = pstSnsType->stSize;
            pstVissChnAttr->enPixelFormat   = pstSnsType->enPixelFormat;
            pstVissChnAttr->stFrameRate.s32SrcFrameRate     = pstSnsType->u32FrameRate;
            return EI_SUCCESS;
        }
    }

    PRT_VISS_ERR("%s does not support this chn configuration", SNS_NAME);

    return EI_FAILURE;

}

CAMERA_OBJ_S stCameraSc4238mipiObj = {
    .pfnRegisterVissCallback    = CAMERA_RegisterVissCallback,
    .pfnUnRegisterVissCallback  = CAMERA_UnregisterVissCallback,
    .pfnRegisterIspCallback     = CAMERA_RegisterIspCallback,
    .pfnUnRegisterIspCallback   = CAMERA_UnregisterIspCallback,
    .pfnGetVissDevAttrBySns     = CAMERA_GetVissDevAttrBySns,
    .pfnGetVissChnAttrBySns     = CAMERA_GetVissChnAttrBySns,
};

#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */

